package org.jeecg.modules.ParameterModule.controller;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.session.SqlSession;
import org.apache.shiro.SecurityUtils;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.modules.ParameterModule.entity.*;
import org.jeecg.modules.ParameterModule.service.CategoryInfoService;
import org.jeecg.modules.ParameterModule.service.LocationService;
import org.jeecg.modules.alipay.init.ProjectInit;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import java.sql.*;
import java.text.SimpleDateFormat;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * 仓库配置
 * */
@Api(tags="仓库配置")
@RestController
@RequestMapping("/location/configuration")
@Slf4j
public class LocationController {
    @Autowired
    private LocationService locationService;
    //线程
    private ExecutorService executorService = Executors.newFixedThreadPool(20);

    /**
     * 仓库的分页列表
     * @param pageNo
     * @param pageSize
     * @return
     */
    @GetMapping(value = "/warehousePagelist")
    public Result<?> queryWarehouse_pagelist(@RequestParam(name="pageNo", defaultValue="1") final Integer pageNo,
                                            @RequestParam(name="pageSize", defaultValue="10") final Integer pageSize,
                                            String queryName, String queryCode) {
        Page<WarehouseInfo> page = new Page<WarehouseInfo>(pageNo, pageSize);
        IPage<WarehouseInfo> pageList = locationService.query_WarehousePageList(page,queryName,queryCode);
        return Result.ok(pageList);
    }

    /**
     * 添加仓库
     * @param
     * @return boolean
     */
    @PostMapping(value = "/add_warehouse")
    @ResponseBody
    @Transactional(rollbackFor = Exception.class)
    public Result<?> add_warehouse(@RequestBody WarehouseInfo testInfo) {
        //执行逻辑前先进行非空验证
        if(testInfo.getWarehouseName()==null || "".equals(testInfo.getWarehouseName())){
            return Result.error("仓库名称不能为空");
        }else if(testInfo.getWarehouseCode()==null || "".equals(testInfo.getWarehouseCode())){
            return Result.error("仓库编码不能为空");
        }else if(testInfo.getContact()==null || "".equals(testInfo.getContact())){
            return Result.error("联系人不能为空");
        }else if(testInfo.getContactPhone()==null || "".equals(testInfo.getContactPhone())){
            return Result.error("联系电话不能为空");
        }else {
            //获取登录用户信息
            LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
            String sys_org_code = sysUser.getOrgCode();
            String create_by = sysUser.getUsername();
            //赋值创建人信息
            testInfo.setCreateBy(create_by);
            testInfo.setSysOrgCode(sys_org_code);
            int code = locationService.add_warehouse(testInfo);
            if(code==0){
                return Result.ok("添加成功");
            }else if(code==1){
                return Result.error("添加失败");
            }else if(code==2){
                return Result.error("该仓库编号已存在，请重新设置");
            }else if(code==3){
                return Result.error("该仓库名称已存在，请重新设置");
            }
            else {
                return Result.error("参数错误，请重新添加");
            }
        }
    }

    /**
     * 修改仓库
     * @param
     * @return boolean
     */
    @PutMapping(value = "/update_warehouse")
    @ResponseBody
    @Transactional(rollbackFor = Exception.class)
    public Result<?> update_warehouse(@RequestBody WarehouseInfo testInfo) {
        //执行逻辑前先进行非空验证
        if(testInfo.getWarehouseName()==null || "".equals(testInfo.getWarehouseName())){
            return Result.error("仓库名称不能为空");
        }else if(testInfo.getContact()==null || "".equals(testInfo.getContact())){
            return Result.error("联系人不能为空");
        }else if(testInfo.getContactPhone()==null || "".equals(testInfo.getContactPhone())){
            return Result.error("联系电话不能为空");
        }else {
            //获取登录用户信息
            LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
            String sys_org_code = sysUser.getOrgCode();
            String create_by = sysUser.getUsername();
            //赋值创建人信息
            testInfo.setUpdateBy(create_by);
            testInfo.setSysOrgCode(sys_org_code);
            int code = locationService.update_warehouse(testInfo);
            if(code==0){
                return Result.ok("编辑成功");
            }else if(code==1){
                return Result.error("编辑失败");
            }else if(code==2){
                return Result.error("该仓库编号已存在，请重新设置");
            }else if(code==3){
                return Result.error("该仓库名称已存在，请重新设置");
            }
            else {
                return Result.error("参数错误，请重新添加");
            }
        }
    }

    /**
     * 查询所有仓库
     * @return
     */
    @GetMapping(value = "/query_allwarehouse")
    public Result<?> query_allwarehouse(){
        List<WarehouseInfo> datalist = locationService.query_allwarehouse();
        if(datalist.size()>0){
            return Result.ok(datalist);
        }else{
            return Result.error("未找到对应数据");
        }
    }

    /**
     * id查询仓库
     * @return
     */
    @GetMapping(value = "/query_warehouseById")
    public Result<?> query_dingzhiBydingzhiId(@RequestParam(name="id")String id){
        WarehouseInfo datainfo = locationService.query_warehouseById(id);
        if(datainfo!=null){
            return Result.ok(datainfo);
        }else{
            return Result.error("未找到对应数据");
        }
    }


    /**
     * 库区的分页列表
     * @param pageNo
     * @param pageSize
     * @return
     */
    @GetMapping(value = "/reservoirPagelist")
    public Result<?> queryreservoir_pagelist(@RequestParam(name="pageNo", defaultValue="1") final Integer pageNo,
                                             @RequestParam(name="pageSize", defaultValue="10") final Integer pageSize,
                                             String topId,String queryName, String queryCode) {
        Page<ReservoirInfo> page = new Page<ReservoirInfo>(pageNo, pageSize);
        IPage<ReservoirInfo> pageList = locationService.query_ReservoirPageList(page,topId,queryName,queryCode);
        return Result.ok(pageList);
    }

    /**
     * 添加库区
     * @param
     * @return boolean
     */
    @PostMapping(value = "/add_reservoir")
    @ResponseBody
    @Transactional(rollbackFor = Exception.class)
    public Result<?> add_reservoir(@RequestBody ReservoirInfo testInfo) {
        //执行逻辑前先进行非空验证
        if(testInfo.getReservoirName()==null || "".equals(testInfo.getReservoirName())){
            return Result.error("库区名称不能为空");
        }else if(testInfo.getReservoirCode()==null || "".equals(testInfo.getReservoirCode())){
            return Result.error("库区编码不能为空");
        }else if(testInfo.getNumbers()==null || "".equals(testInfo.getNumbers())){
            return Result.error("排序序号不能为空");
        }else {
            //获取登录用户信息
            LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
            String sys_org_code = sysUser.getOrgCode();
            String create_by = sysUser.getUsername();
            //赋值创建人信息
            testInfo.setCreateBy(create_by);
            testInfo.setSysOrgCode(sys_org_code);
            int code = locationService.add_Reservoir(testInfo);
            if(code==0){
                return Result.ok("添加成功");
            }else if(code==1){
                return Result.error("添加失败");
            }else if(code==2){
                return Result.error("该库区编号已存在，请重新设置");
            }else if(code==3){
                return Result.error("该库区名称已存在，请重新设置");
            }
            else {
                return Result.error("参数错误，请重新添加");
            }
        }
    }

    /**
     * 修改库区
     * @param
     * @return boolean
     */
    @PutMapping(value = "/update_reservoir")
    @ResponseBody
    @Transactional(rollbackFor = Exception.class)
    public Result<?> update_reservoir(@RequestBody ReservoirInfo testInfo) {
        //执行逻辑前先进行非空验证
        if(testInfo.getReservoirName()==null || "".equals(testInfo.getReservoirName())){
            return Result.error("库区名称不能为空");
        }else if(testInfo.getReservoirCode()==null || "".equals(testInfo.getReservoirCode())){
            return Result.error("库区编码不能为空");
        }else if(testInfo.getNumbers()==null || "".equals(testInfo.getNumbers())){
            return Result.error("排序序号不能为空");
        }else {
            //获取登录用户信息
            LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
            String sys_org_code = sysUser.getOrgCode();
            String create_by = sysUser.getUsername();
            //赋值创建人信息
            testInfo.setUpdateBy(create_by);
            testInfo.setSysOrgCode(sys_org_code);
            int code = locationService.update_Reservoir(testInfo);
            if(code==0){
                return Result.ok("编辑成功");
            }else if(code==1){
                return Result.error("编辑失败");
            }else if(code==2){
                return Result.error("该库区编号已存在，请重新设置");
            }else if(code==3){
                return Result.error("该库区名称已存在，请重新设置");
            }
            else {
                return Result.error("参数错误，请重新添加");
            }
        }
    }
    /**
     * 删除/启用库区
     * @param
     * @return boolean
     */
    @PutMapping(value = "/change_reservoir_status")
    @ResponseBody
    @Transactional(rollbackFor = Exception.class)
    public Result<?> change_reservoir_status(@RequestBody Map<String,Object> params) {
        String id = params.get("id").toString();
        String status = params.get("status").toString();
        try {
            int code = locationService.delete_Reservoir(id,status);
            if(code==0){
                return Result.ok("操作成功");
            }else {
                return Result.error("操作失败");
            }
        }catch (Exception e){
            return Result.error("操作失败，参数错误");
        }
    }
    /**
     * id查询库区
     * @return
     */
    @GetMapping(value = "/query_reservoirById")
    public Result<?> query_reservoirById(@RequestParam(name="id")String id){
        ReservoirInfo datainfo = locationService.query_ReservoirInfoById(id);
        if(datainfo!=null){
            return Result.ok(datainfo);
        }else{
            return Result.error("未找到对应数据");
        }
    }


    /**
     * 货架的分页列表
     * @param pageNo
     * @param pageSize
     * @return
     */
    @GetMapping(value = "/ShelvesPagelist")
    public Result<?> queryShelves_pagelist(@RequestParam(name="pageNo", defaultValue="1") final Integer pageNo,
                                             @RequestParam(name="pageSize", defaultValue="10") final Integer pageSize,
                                             String topId,String queryName, String queryCode) {
        Page<ShelvesInfo> page = new Page<ShelvesInfo>(pageNo, pageSize);
        IPage<ShelvesInfo> pageList = locationService.query_shelvesPageList(page,topId,queryName,queryCode);
        return Result.ok(pageList);
    }
    /**
     * 添加货架
     * @param
     * @return boolean
     */
    @PostMapping(value = "/add_Shelves")
    @ResponseBody
    @Transactional(rollbackFor = Exception.class)
    public Result<?> add_Shelves(@RequestBody ShelvesInfo testInfo) throws Exception {
        Long start_time = System.currentTimeMillis();
        //执行逻辑前先进行非空验证
        if(testInfo.getShelvesName()==null || "".equals(testInfo.getShelvesName())){
            return Result.error("货架名称不能为空");
        }else if(testInfo.getShelvesCode()==null || "".equals(testInfo.getShelvesCode())){
            return Result.error("货架编码不能为空");
        }else if(testInfo.getNumbers()==null || "".equals(testInfo.getNumbers())){
            return Result.error("排序序号不能为空");
        }else if(testInfo.getLayer()==null || "".equals(testInfo.getLayer())){
            return Result.error("货架行数不能为空");
        }else if(testInfo.getColumns()==null || "".equals(testInfo.getColumns())){
            return Result.error("货架列数不能为空");
        }
        else {
            //获取登录用户信息
            LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
            String sys_org_code = sysUser.getOrgCode();
            String create_by = sysUser.getUsername();
            //赋值创建人信息
            testInfo.setCreateBy(create_by);
            testInfo.setSysOrgCode(sys_org_code);
            //赋值id
            Long startTs = System.currentTimeMillis(); // 当前时间戳
            //8位随机数
            int random=new Random().nextInt(1000000)+1;//为变量赋随机值1-99999999;
            int random2=new Random().nextInt(100)+1;//为变量赋随机值1-99999999;
            String huojiaID = startTs.toString()+random;
            String hao = startTs.toString()+random2;
            testInfo.setId(huojiaID);
            int code = locationService.add_shelves(testInfo);
            //获取层数*列数
            int sumnum = testInfo.getLayer() * testInfo.getColumns();
            if(code==0){
                // 另起线程处理业务
                executorService.execute(new Runnable() {
                    @Override
                    public void run() {
                        //获取数据连接池
                        Connection con = null;
                        //jdbc驱动
                        String driver = CommonConstant.JDBC_DRIVER;
                        //数据库URL地址
                        String url = CommonConstant.JDBC_URL;
                        //连接数据库的用户名及密码
                        String userName = CommonConstant.JDBC_USERNAME;
                        String password = CommonConstant.JDBC_PASSWORD;
                        //SQL执行对象
                        PreparedStatement preparedStatement;
                        try {
                            //开始时间
                            Long startTime = System.currentTimeMillis();
                            //注册JDBC驱动程序
                            Class.forName(driver);
                            //建立连接
                            con = DriverManager.getConnection(url, userName, password);
                            //准备SQL
                            String sql = "insert into mlcc_third_location(shelves_id,location_name,numbers,location_code,remark,sys_org_code,create_by,create_time) values(?,?,?,?,?,?,?,now())";
                            /**
                             * 取消自动提交
                             * 没有setAutoCommit(false)；那么对于每一条insert语句，都会产生一条log
                             * 写入磁盘，所以虽然设置了批量插入，但其效果就像单条插入一样，导致插入速度十分缓慢
                             */
                            con.setAutoCommit(false);
                            //预编译SQL
                            preparedStatement = con.prepareStatement(sql);
                            //循环插入100000万条数据
                            for (int i = 0; i < sumnum; i++) {
                                //赋值库位
                                int num = i+1;
                                preparedStatement.setString(1, huojiaID);
                                preparedStatement.setString(2, "库位"+num);
                                preparedStatement.setDouble(3, Double.parseDouble(num+""));
                                preparedStatement.setString(4, huojiaID+"-K"+num);
                                preparedStatement.setString(5, "自增库位");
                                preparedStatement.setString(6, sys_org_code);
                                preparedStatement.setString(7, create_by);
                                preparedStatement.addBatch();
                                if(sumnum>10000){
                                    // 1w条记录插入一次
                                    if (i % 10000 == 0) {
                                        preparedStatement.executeBatch();
                                        con.commit();
                                    }
                                }else if(sumnum>1000 && sumnum<=10000){
                                    // 1千条记录插入一次
                                    if (i % 1000 == 0) {
                                        preparedStatement.executeBatch();
                                        con.commit();
                                    }
                                }else if(sumnum>100 && sumnum<=1000){
                                    // 1百条记录插入一次
                                    if (i % 100 == 0) {
                                        preparedStatement.executeBatch();
                                        con.commit();
                                    }
                                }else if(sumnum>10 && sumnum<=100){
                                    // 10条记录插入一次
                                    if (i % 10 == 0) {
                                        preparedStatement.executeBatch();
                                        con.commit();
                                    }
                                }
                            }
                            // 最后插入不足1w条的数据
                            preparedStatement.executeBatch();
                            con.commit();
                            Long endTime = System.currentTimeMillis();
                            System.out.println("插入10万条数据共耗时 ： " + ((endTime - startTime) / 1000) + "秒");
                        } catch (ClassNotFoundException e) {
                            System.out.println("数据库驱动没有安装");
                        } catch (SQLException e) {
                            e.printStackTrace();
                            System.out.println("数据库连接失败");
                        } finally {
                            if (con != null) {
                                try {
                                    con.close();
                                } catch (SQLException throwables) {
                                    throwables.printStackTrace();
                                }
                            }
                        }
                    }
                });
                return Result.ok("添加成功，库位正在自动创建中，请稍后");
            }else if(code==1){
                return Result.error("添加失败");
            }else if(code==2){
                return Result.error("该货架编号已存在，请重新设置");
            }else if(code==3){
                return Result.error("该货架名称已存在，请重新设置");
            }
            else {
                return Result.error("参数错误，请重新添加");
            }
        }
    }

    /**
     * 修改货架
     * @param
     * @return boolean
     */
    @PutMapping(value = "/update_Shelves")
    @ResponseBody
    @Transactional(rollbackFor = Exception.class)
    public Result<?> update_Shelves(@RequestBody ShelvesInfo testInfo) {
        //执行逻辑前先进行非空验证
        if(testInfo.getShelvesName()==null || "".equals(testInfo.getShelvesName())){
            return Result.error("货架名称不能为空");
        }else if(testInfo.getShelvesCode()==null || "".equals(testInfo.getShelvesCode())){
            return Result.error("货架编码不能为空");
        }else if(testInfo.getNumbers()==null || "".equals(testInfo.getNumbers())){
            return Result.error("排序序号不能为空");
        }else if(testInfo.getLayer()==null || "".equals(testInfo.getLayer())){
            return Result.error("货架行数不能为空");
        }else if(testInfo.getColumns()==null || "".equals(testInfo.getColumns())){
            return Result.error("货架列数不能为空");
        }else {
            //获取登录用户信息
            LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
            String sys_org_code = sysUser.getOrgCode();
            String create_by = sysUser.getUsername();
            //赋值创建人信息
            testInfo.setUpdateBy(create_by);
            testInfo.setSysOrgCode(sys_org_code);
            int code = locationService.update_shelves(testInfo);
            if(code==0){
                return Result.ok("编辑成功");
            }else if(code==2){
                return Result.error("该货架编号已存在，请重新设置");
            }else if(code==3){
                return Result.error("该货架名称已存在，请重新设置");
            }
            else if(code==1){
                return Result.error("编辑失败");
            }else {
                return Result.error("参数错误，请重新添加");
            }
        }
    }
    /**
     * 删除/启用货架
     * @param
     * @return boolean
     */
    @PutMapping(value = "/change_Shelves_status")
    @ResponseBody
    @Transactional(rollbackFor = Exception.class)
    public Result<?> change_Shelves_status(@RequestBody Map<String,Object> params) {
        String id = params.get("id").toString();
        String status = params.get("status").toString();
        try {
            int code = locationService.delete_shelves(id,status);
            if(code==0){
                return Result.ok("操作成功");
            }else {
                return Result.error("操作失败");
            }
        }catch (Exception e){
            return Result.error("操作失败，参数错误");
        }
    }
    /**
     * id查询货架
     * @return
     */
    @GetMapping(value = "/query_ShelvesById")
    public Result<?> query_ShelvesById(@RequestParam(name="id")String id){
        ShelvesInfo datainfo = locationService.query_shelvesInfoById(id);
        if(datainfo!=null){
            return Result.ok(datainfo);
        }else{
            return Result.error("未找到对应数据");
        }
    }


    /**
     * 库位的分页列表
     * @param pageNo
     * @param pageSize
     * @return
     */
    @GetMapping(value = "/LocaltionPagelist")
    public Result<?> queryLocaltion_pagelist(@RequestParam(name="pageNo", defaultValue="1") final Integer pageNo,
                                           @RequestParam(name="pageSize", defaultValue="10") final Integer pageSize,
                                           String topId,String queryName, String queryCode) {
        Page<LocationInfo> page = new Page<LocationInfo>(pageNo, pageSize);
        IPage<LocationInfo> pageList = locationService.query_LocationPageList(page,topId,queryName,queryCode);
        return Result.ok(pageList);
    }
    /**
     * 添加库位
     * @param
     * @return boolean
     */
    @PostMapping(value = "/add_Localtion")
    @ResponseBody
    @Transactional(rollbackFor = Exception.class)
    public Result<?> add_Localtion(@RequestBody LocationInfo testInfo) {
        //执行逻辑前先进行非空验证
        if(testInfo.getLocationName()==null || "".equals(testInfo.getLocationName())){
            return Result.error("库位名称不能为空");
        }else if(testInfo.getLocationCode()==null || "".equals(testInfo.getLocationCode())){
            return Result.error("库位编码不能为空");
        }else if(testInfo.getNumbers()==null || "".equals(testInfo.getNumbers())){
            return Result.error("排序序号不能为空");
        }
        else {
            int sum = 0;
            //根据货架id统计下面的现有的库位
            int count_location = locationService.count_shelves_location(testInfo.getShelvesId());
            //根据货架id查询货架详情
            ShelvesInfo shelvesInfo = locationService.query_shelvesInfoById(testInfo.getShelvesId());
            if(shelvesInfo!=null){
                sum = shelvesInfo.getColumns() * shelvesInfo.getLayer();
            }
            if(count_location>=sum){
                return Result.error("该货架库位已满，请删除其它库位再进行添加");
            }
            //获取登录用户信息
            LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
            String sys_org_code = sysUser.getOrgCode();
            String create_by = sysUser.getUsername();
            //赋值创建人信息
            testInfo.setCreateBy(create_by);
            testInfo.setSysOrgCode(sys_org_code);
            int code = locationService.add_Location(testInfo);
            if(code==0){
                return Result.ok("添加成功");
            }else if(code==1){
                return Result.error("添加失败");
            }else if(code==2){
                return Result.error("该库位编号已存在，请重新设置");
            }else if(code==3){
                return Result.error("该库位名称已存在，请重新设置");
            }
            else {
                return Result.error("参数错误，请重新添加");
            }
        }
    }
    /**
     * 修改库位
     * @param
     * @return boolean
     */
    @PutMapping(value = "/update_Location")
    @ResponseBody
    @Transactional(rollbackFor = Exception.class)
    public Result<?> update_Location(@RequestBody LocationInfo testInfo) {
        //执行逻辑前先进行非空验证
        if(testInfo.getLocationName()==null || "".equals(testInfo.getLocationName())){
            return Result.error("库位名称不能为空");
        }else if(testInfo.getLocationCode()==null || "".equals(testInfo.getLocationCode())){
            return Result.error("库位编码不能为空");
        }else if(testInfo.getNumbers()==null || "".equals(testInfo.getNumbers())){
            return Result.error("排序序号不能为空");
        }else {
            //获取登录用户信息
            LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
            String sys_org_code = sysUser.getOrgCode();
            String create_by = sysUser.getUsername();
            //赋值创建人信息
            testInfo.setUpdateBy(create_by);
            testInfo.setSysOrgCode(sys_org_code);
            int code = locationService.update_Location(testInfo);
            if(code==0){
                return Result.ok("编辑成功");
            }else if(code==1){
                return Result.error("编辑失败");
            }else {
                return Result.error("参数错误，请重新添加");
            }
        }
    }
    /**
     * 删除/启用库位
     * @param
     * @return boolean
     */
    @PutMapping(value = "/change_Location_status")
    @ResponseBody
    @Transactional(rollbackFor = Exception.class)
    public Result<?> change_Location_status(@RequestBody Map<String,Object> params) {
        String id = params.get("id").toString();
        String status = params.get("status").toString();
        try {
            int code = locationService.delete_Location(id,status);
            if(code==0){
                return Result.ok("操作成功");
            }else {
                return Result.error("操作失败");
            }
        }catch (Exception e){
            return Result.error("操作失败，参数错误");
        }
    }
    /**
     * id查询库位
     * @return
     */
    @GetMapping(value = "/query_LocationById")
    public Result<?> query_LocationById(@RequestParam(name="id")String id){
        LocationInfo datainfo = locationService.query_LocationInfoById(id);
        if(datainfo!=null){
            return Result.ok(datainfo);
        }else{
            return Result.error("未找到对应数据");
        }
    }

}
